home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
jaz_clib.arc
/
WPRINTF.C
< prev
next >
Wrap
Text File
|
1989-04-09
|
6KB
|
291 lines
/*
* KPRINTF -- "kernel" formatted print routines for DeSmet C
*
* Copyright 1985 by John McNamee.
* This software may be freely copied for non-commercial use.
* Commercial use requires the written permission of the author.
*
* John McNamee
* 7560 McLaren Ave.
* Canoga Park, CA 91307
*
* CompuServe: 70235,1345
* Usenet: decvax!philabs!sbcs!bnl!jpm
* Internet: jpm@BNL.ARPA
*/
/*
* Overview of this package:
*
* kprintf() and ksprintf() should act exactly like printf and sprintf, except
* they don't do floating point. The idea is to avoid bringing in the floating
* point and file handling library routines that get loaded every time the
* normal printf or sprintf are called. My routines add less than 2K to
* program size, while normal printf adds over 6K. Of course, if you are going
* to do file I/O or floating point you mind as well use the normal routines.
* These functions are for writing programs programs that wouldn't otherwise
* bring in all that code.
*
* I'm sure this code could be made smaller and faster. This was done "quick
* and dirty" and I don't want to hear from anybody about bad coding style.
* This really should be written in assembly language, but who has the time?
*/
/*
* Notes on converting to something other than DeSmet C:
*
* It shouldn't be too hard to move these routines to another C compiler.
* The main thing you will have to do is check if calling putchar() brings
* in the whole file I/O library of your compiler. It doesn't on DeSmet.
* If yours does, write something that does tha same thing (its just a simple
* call to MSDOS), and use it instead of putchar in the kprintf() function.
*/
/* "FAST" is the type that produces the fastest local variables. */
/* It is normally "register", but Intel chips are very braindamaged and */
/* don't have enough registers, so you must use "static". */
#define FAST register
static int left_flag, do_padding, num1, num2;
static char outbuf[32], *sp_ptr, pad_character;
static int wrow,wcol,wstart,wend;
/*
* Print on terminal
*/
extern int _row1,_row2,_col1,_col2,_attr,g_row,g_col,g_fore,g_back;
#include <ctype.h>
wprintf(ctrl, args)
char *ctrl, *args;
{
int putachar();
jzgetcur(&wrow,&wcol,&wstart,&wend);
doprint(putachar, ctrl, &args);
}
store_chr(ch)
int ch;
{
*sp_ptr++ = ch;
}
/*
* Generalized routine
*/
static doprint(outfunc, ctrl, argp)
int (*outfunc)();
char *ctrl, *argp;
{
FAST int long_flag;
FAST char *cp, ch;
FAST int dot_flag;
for (;*ctrl;ctrl++) {
if (*ctrl!='%') {
(*outfunc)(*ctrl);
continue;
}
dot_flag=long_flag=left_flag=do_padding=0;
num2=32767;
pad_character=' ';
try_next: ch = *(++ctrl);
if (isdigit(ch)) {
if (dot_flag)
num2=getnum(&ctrl);
else {
if (ch=='0')
pad_character='0';
num1=getnum(&ctrl);
do_padding=1;
}
ctrl--;
goto try_next;
}
switch (tolower(ch)) {
case 0:
return;
case '%':
(*outfunc)('%');
continue;
case '-':
left_flag=1;
break;
case '.':
dot_flag=1;
break;
case 'l':
long_flag=1;
break;
case 'd':
if (long_flag || ch=='D') {
outnum(outfunc, *((long *)argp), 10L);
argp+=sizeof(long);
continue;
} else {
outnum(outfunc, (long)(*((int *)argp)), 10L);
argp+=sizeof(int);
continue;
}
case 'x':
if (long_flag || ch=='X') {
outnum(outfunc, *((long *)argp), 16L);
argp+=sizeof(long);
continue;
} else {
outnum(outfunc, (long)(*((int *)argp)), 16L);
argp+=sizeof(int);
continue;
}
case 'o':
if (long_flag || ch=='X') {
outnum(outfunc, *((long *)argp), 8L);
argp+=sizeof(long);
continue;
} else {
outnum(outfunc, (long)(*((int *)argp)), 8L);
argp+=sizeof(int);
continue;
}
case 's':
outs(outfunc, *((char **)argp));
argp+=sizeof(char *);
continue;
case 'c':
(*outfunc)(*((int *)argp));
argp+=sizeof(int);
continue;
case 'f':
case 'e':
case 'g':
do_padding=0;
num2=32767;
outs(outfunc, "*No floating point in kprintf!*");
continue;
default:
continue;
}
goto try_next;
}
}
/*
* Function used to output a line
*/
static outs(outfunc, lp)
int (*outfunc)();
char *lp;
{
FAST int i, len;
/* Blank pad on left if needed */
if (do_padding && !left_flag && (len=strlen(lp))<num1)
for (i=len; i<num1; i++)
(*outfunc)(pad_character);
/* Now output string */
while (*lp && num2--)
(*outfunc)(*lp++);
/* Blank pad on right if needed */
if (do_padding && left_flag && (len=strlen(lp))<num1)
for (i=len; i<num1; i++)
(*outfunc)(pad_character);
}
/*
* Output a number
*/
static outnum(outfunc, num, base)
int (*outfunc)();
long num, base;
{
FAST char *cp;
FAST int i, len, negative;
static char digits[]="0123456789ABCDEF";
/* Build number (backwards) in outbuf */
if (num<0L) {
negative = 1;
num = -num;
} else
negative = 0;
cp=outbuf;
do {
*cp++ = digits[num%base];
} while ((num/=base) > 0);
if (negative)
*cp++ = '-';
*cp-- = 0;
len=strlen(outbuf);
/* Blank pad on left if needed */
if (do_padding && !left_flag && len<num1)
for (i=len; i<num1; i++)
(*outfunc)(pad_character);
/* Now output the buffer in reverse order */
while (cp>=outbuf)
(*outfunc)(*cp--);
/* Blank pad on right if needed */
if (do_padding && left_flag && len<num1)
for (i=len; i<num1; i++)
(*outfunc)(pad_character);
}
/*
* Get a number from the control string.
*
* This function takes a pointer to a character pointer (which it
* updates to point to the character after the end of the number)
* and returns an integer result.
*/
static getnum(linep)
char **linep;
{
FAST int n;
FAST char *cp;
cp = *linep;
n = 0;
while (isdigit(*cp))
n = n*10 + ((*cp++)-'0');
*linep = cp;
return(n);
}
static putachar(fch)
char fch;
{
if (wcol > _col2) {
wcol = _col1;
if (wrow == _row2)
jzscrlup(_row1 << 8 | _col1,_row2 << 8 | _col2,1,_attr);
else
++ wrow;
}
if (fch) {
jzwrtchr(fch,_attr,1);
++ wcol;
}
g_row=wrow;
g_col=wcol;
jzloccur(wrow,wcol);
}